import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class Student {
    public String name;
    public int age;
    private int grade;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {

    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", grade=" + grade +
                '}';
    }

    private String print() {
        System.out.println("私有方法调用");
        return "私有方法调用";
    }
}

public class Test {
    public static void main1(String[] args) throws ClassNotFoundException {
        Student student = new Student("zhangsan", 18);

        //创建Class类的三种方法 Class是反射的基础
        //方式一
        Class clazz = Student.class;
        //方式二
        Class clazz2 = student.getClass();
        //方式三
        Class clazz3 = Class.forName("Student");


    }

    /**
     * 反射的基本操作
     * 1.创建运行时类的对象
     * 2.获取运行时类的完整结构
     * 3.调用运行时类的指定结果
     */
    //1.创建运行时类的对象
    public static void main2(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //方式1
        //Class的newInstance()方法
        //前提是类中必须有空参的构造方法 且构造方法的权限必须保证在反射这里可以调用

        //第一步创建Class对象
        Class clazz = Class.forName("Student");

        //实例Student类
        Student stu = (Student) clazz.newInstance();
        System.out.println(stu);
    }

    public static void main3(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //创建Class对象
        Class clazz = Class.forName("Student");

        //获取多个参数的构造器
        Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class);

        //如果构造方法我们的访问权限不够 还想要访问 则调用下面的方法
        constructor.setAccessible(true);

        //根据构造器实例化类
        Student student = (Student) constructor.newInstance("zhangsan", 18);

        System.out.println(student);
    }

    /**
     * 获取运行时类的完整结构
     * 可以获取：包、修饰符、类型名、父类（包括泛型父类）、父接口（包括泛型父接口）、成员（属性、构造器、方法）
     */
    public static void main1(String[] args) {

    }
}























